package com.qsl.ssyx.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qsl.ssyx.Service.RabbitService;
import com.qsl.ssyx.common.constant.RedisConst;
import com.qsl.ssyx.common.exception.BusinessException;
import com.qsl.ssyx.common.result.ResultCodeEnum;
import com.qsl.ssyx.constant.MqConst;
import com.qsl.ssyx.model.product.SkuAttrValue;
import com.qsl.ssyx.model.product.SkuImage;
import com.qsl.ssyx.model.product.SkuPoster;
import com.qsl.ssyx.product.mapper.SkuInfoMapper;
import com.qsl.ssyx.model.product.SkuInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qsl.ssyx.product.service.SkuAttrValueService;
import com.qsl.ssyx.product.service.SkuImageService;
import com.qsl.ssyx.product.service.SkuInfoService;
import com.qsl.ssyx.product.service.SkuPosterService;
import com.qsl.ssyx.vo.product.SkuInfoQueryVo;
import com.qsl.ssyx.vo.product.SkuInfoVo;
import com.qsl.ssyx.vo.product.SkuStockLockVo;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * <p>
 * sku信息 服务实现类
 * </p>
 *
 * @author 青衫泪
 * @since 2023-08-10
 */
@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuInfoService {


    // sku商品平台属性
    @Autowired
    private SkuAttrValueService skuAttrValueService;
    // sku商品图片信息
    @Autowired
    private SkuImageService skuImageService;
    // sku商品海报
    @Autowired
    private SkuPosterService skuPosterService;
    // RabbitMQ
    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private RedisTemplate redisTemplate;
    // redis分布式锁
    @Autowired
    private RedissonClient redissonClient;

    //    条件分页查询
    @Override
    public IPage<SkuInfo> selectPage(Page<SkuInfo> pageParam, SkuInfoQueryVo skuInfoQueryVo) {
        LambdaQueryWrapper<SkuInfo> lqw = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(skuInfoQueryVo.getKeyword())) { // 商品名稱
            lqw.like(SkuInfo::getSkuName, skuInfoQueryVo.getKeyword());
        }
        if (!StringUtils.isEmpty(skuInfoQueryVo.getCategoryId())) { // 商品分類id
            lqw.eq(SkuInfo::getCategoryId, skuInfoQueryVo.getCategoryId());
        }
        if (!StringUtils.isEmpty(skuInfoQueryVo.getSkuType())) { // 商品類型：商品类型：0->普通商品 1->秒杀商品
            lqw.eq(SkuInfo::getSkuType, skuInfoQueryVo.getSkuType());
        }
        lqw.orderByDesc(SkuInfo::getId); // 倒序
        Page<SkuInfo> skuInfoPage = baseMapper.selectPage(pageParam, lqw);
        return skuInfoPage;
    }

    //    商品上、下架状态
    @Override
    public boolean updatePublishStatus(Long id, Integer publishStatus) {
        SkuInfo skuInfo = new SkuInfo();
        skuInfo.setId(id);
        skuInfo.setPublishStatus(publishStatus);
        int flag = baseMapper.updateById(skuInfo);
        Long skuId = id;  // 注意：此处的id要和监听器的id对上，否则监听不到。

        // TODO 整合mq把数据同步到es里
        if (publishStatus == 1) { // 商品上架
            //商品上架：发送mq消息同步es
            rabbitService.sendMessage(MqConst.EXCHANGE_GOODS_DIRECT, MqConst.ROUTING_GOODS_UPPER, skuId);
        } else { // 下架
            //商品上架：发送mq消息同步es
            rabbitService.sendMessage(MqConst.EXCHANGE_GOODS_DIRECT, MqConst.ROUTING_GOODS_LOWER, skuId);
        }
        return flag > 0;
    }

    // 修改商品审核状态
    @Override
    public boolean updateCheckStatus(Long id, Integer status) {
        SkuInfo skuInfo = new SkuInfo();
        skuInfo.setId(id);
        skuInfo.setCheckStatus(status);
        int flag = baseMapper.updateById(skuInfo);

        return flag > 0;
    }

    //    是否新人专享
    @Override
    public boolean isNewPerson(Long id, Integer isNewPerson) {
        SkuInfo skuInfo = new SkuInfo();
        skuInfo.setId(id);
        skuInfo.setIsNewPerson(isNewPerson);
        int flag = baseMapper.updateById(skuInfo);

        return flag > 0;
    }

    // 新增- sku_info,sku_attr_value,sku_image,sku_poster
    @Override
    public boolean saveSkuInfo(SkuInfoVo skuInfoVo) {
        // 1. 添加sku基本信息
        SkuInfo skuInfo = new SkuInfo();
        BeanUtils.copyProperties(skuInfoVo, skuInfo); // skuInfoVo 数据复制到  skuInfo对象
        int insert = baseMapper.insert(skuInfo);

        // 2. 添加sku_attr_value商品属性
        List<SkuAttrValue> skuAttrValueList = skuInfoVo.getSkuAttrValueList();
        if (!CollectionUtils.isEmpty(skuAttrValueList)) { // 集合数据不为空
            for (SkuAttrValue skuAttrValue : skuAttrValueList) {
                skuAttrValue.setSkuId(skuInfo.getId());
            }
            boolean flagSkuAttrValue = skuAttrValueService.saveBatch(skuAttrValueList);
        }

        // 3. 添加sku_image 商品图片信息
        List<SkuImage> skuImagesList = skuInfoVo.getSkuImagesList();
        if (!CollectionUtils.isEmpty(skuImagesList)) {
            for (SkuImage skuImage : skuImagesList) {
                skuImage.setSkuId(skuInfo.getId());
            }
            boolean flagSkuImage = skuImageService.saveBatch(skuImagesList);
        }

        // 4. 添加sku_poster 商品海报
        List<SkuPoster> skuPosterList = skuInfoVo.getSkuPosterList();
        if (!CollectionUtils.isEmpty(skuPosterList)) {
            for (SkuPoster skuPoster : skuPosterList) {
                skuPoster.setSkuId(skuInfo.getId());
            }
            boolean flagSkuPoster = skuPosterService.saveBatch(skuPosterList);
        }

        return false;
    }

    //    根据Id查询  sku_info,sku_attr_value,sku_image,sku_poster
    @Override
    public SkuInfoVo getBySkuId(Integer id) {
        // 查询sku_inf，sku基本信息
        SkuInfo skuInfo = baseMapper.selectById(id);
        System.out.println("===>" + skuInfo);

        // 查询sku_attr_value ，sku属性值服务信息
        LambdaQueryWrapper<SkuAttrValue> lqwSkuAttrValue = new LambdaQueryWrapper<>();
        lqwSkuAttrValue.eq(SkuAttrValue::getSkuId, id);
        List<SkuAttrValue> attrValueList = skuAttrValueService.list(lqwSkuAttrValue);

        // 查询sku_image，sku商品图片信息
        LambdaQueryWrapper<SkuImage> lqwSkuImage = new LambdaQueryWrapper<>();
        lqwSkuImage.eq(SkuImage::getSkuId, id);
        List<SkuImage> skuImageList = skuImageService.list(lqwSkuImage);

        // 查询sku_poster，sku商品海报
        LambdaQueryWrapper<SkuPoster> lqwSkuPoster = new LambdaQueryWrapper<>();
        lqwSkuPoster.eq(SkuPoster::getSkuId, id);
        List<SkuPoster> skuPosterList = skuPosterService.list(lqwSkuPoster);

        // 封装最终返回参数
        SkuInfoVo skuInfoVo = new SkuInfoVo();
        BeanUtils.copyProperties(skuInfo, skuInfoVo);
        skuInfoVo.setSkuAttrValueList(attrValueList);
        skuInfoVo.setSkuImagesList(skuImageList);
        skuInfoVo.setSkuPosterList(skuPosterList);

        return skuInfoVo;
    }

    // 修改 sku_info,sku_attr_value,sku_image,sku_poster
    @Override // 此次修改，通过先删除，在新增实现。
    public boolean updateBySkuId(SkuInfoVo skuInfovo) {
        // 修改sku_inf，sku基本信息
        SkuInfo skuInfo = new SkuInfo();
        BeanUtils.copyProperties(skuInfovo, skuInfo);  // skuInfoVo 数据复制到  skuInfo对象
        baseMapper.updateById(skuInfo);

        Long skuId = skuInfo.getId();
        // 修改sku_attr_value ，sku属性值服务信息 ==》先删除，在新增
        LambdaQueryWrapper<SkuAttrValue> lqwSkuAttrValue = new LambdaQueryWrapper<>();
        lqwSkuAttrValue.eq(SkuAttrValue::getSkuId, skuId);
        skuAttrValueService.remove(lqwSkuAttrValue);

        List<SkuAttrValue> skuAttrValueList = skuInfovo.getSkuAttrValueList();
        if (!CollectionUtils.isEmpty(skuAttrValueList)) {
            for (SkuAttrValue skuAttrValue : skuAttrValueList) {
                skuAttrValue.setSkuId(skuId);
            }
            skuAttrValueService.saveBatch(skuAttrValueList);
        }

        // 查询sku_image，sku商品图片信息
        LambdaQueryWrapper<SkuImage> lqwSkuImage = new LambdaQueryWrapper<>();
        lqwSkuImage.eq(SkuImage::getSkuId, skuId);
        skuImageService.remove(lqwSkuImage);

        List<SkuImage> skuImagesList = skuInfovo.getSkuImagesList();
        if (!CollectionUtils.isEmpty(skuImagesList)) {
            for (SkuImage skuImage : skuImagesList) {
                skuImage.setSkuId(skuId);
            }
            skuImageService.saveBatch(skuImagesList);
        }

        // 查询sku_poster，sku商品海报
        LambdaQueryWrapper<SkuPoster> lqwSkuPoster = new LambdaQueryWrapper<>();
        lqwSkuPoster.eq(SkuPoster::getSkuId, skuId);
        skuPosterService.remove(lqwSkuPoster);

        List<SkuPoster> skuPosterList = skuInfovo.getSkuPosterList();
        if (!CollectionUtils.isEmpty(skuPosterList)) {
            for (SkuPoster skuPoster : skuPosterList) {
                skuPoster.setSkuId(skuId);
            }
            skuPosterService.saveBatch(skuPosterList);
        }

        return false;
    }

    // 删除 sku_info,sku_attr_value,sku_image,sku_poster
    @Override
    public boolean removeBySkuId(Integer id) {
        // 删除sku_inf，sku基本信息
        int flag = baseMapper.deleteById(id);

        // 删除sku_attr_value ，sku属性值服务信息
        LambdaQueryWrapper<SkuAttrValue> lqwSkuAttrValue = new LambdaQueryWrapper<>();
        lqwSkuAttrValue.eq(SkuAttrValue::getSkuId, id);
        skuAttrValueService.remove(lqwSkuAttrValue);

        // 删除sku_image，sku商品图片信息
        LambdaQueryWrapper<SkuImage> lqwSkuImage = new LambdaQueryWrapper<>();
        lqwSkuImage.eq(SkuImage::getSkuId, id);
        skuImageService.remove(lqwSkuImage);

        // 删除sku_poster，sku商品海报
        LambdaQueryWrapper<SkuPoster> lqwSkuPoster = new LambdaQueryWrapper<>();
        lqwSkuPoster.eq(SkuPoster::getSkuId, id);
        skuPosterService.remove(lqwSkuPoster);

        // TODO 删除ES数据


        return flag > 0;
    }

    // 批量删除 sku_info,sku_attr_value,sku_image,sku_poster
    @Override
    public boolean removeBySkuIds(List<Integer> idList) {
        // 删除sku_inf，sku基本信息
        int flag = baseMapper.deleteBatchIds(idList);

        // 删除sku_attr_value ，sku属性值服务信息
        LambdaQueryWrapper<SkuAttrValue> lqwSkuAttrValue = new LambdaQueryWrapper<>();
        for (Integer skuId : idList) {
            lqwSkuAttrValue.eq(SkuAttrValue::getSkuId, skuId);
            skuAttrValueService.remove(lqwSkuAttrValue);
        }

        // 删除sku_image，sku商品图片信息
        LambdaQueryWrapper<SkuImage> lqwSkuImage = new LambdaQueryWrapper<>();
        for (Integer skuId : idList) {
            lqwSkuImage.eq(SkuImage::getSkuId, skuId);
            skuImageService.remove(lqwSkuImage);
        }

        // 删除sku_poster，sku商品海报
        LambdaQueryWrapper<SkuPoster> lqwSkuPoster = new LambdaQueryWrapper<>();
        for (Integer skuId : idList) {
            lqwSkuPoster.eq(SkuPoster::getSkuId, skuId);
            skuPosterService.remove(lqwSkuPoster);
        }

        return flag > 0;
    }

    //    根据skuId获取商品信息列表
    @Override
    public List<SkuInfo> getSkuInfoListById(Long skuId) {
        LambdaQueryWrapper<SkuInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SkuInfo::getId, skuId);
        lqw.orderByDesc(SkuInfo::getId); // 倒序
        List<SkuInfo> skuInfoList = baseMapper.selectList(lqw);
        return skuInfoList;
    }


    //    根据商品名称 查询SkuInfo集合
    @Override
    public List<SkuInfo> getSkuInfosBySkuName(String skuName) {
        LambdaQueryWrapper<SkuInfo> lqw = new LambdaQueryWrapper<>();
        lqw.like(SkuInfo::getSkuName, skuName);
        lqw.orderByDesc(SkuInfo::getId); // 倒序
        List<SkuInfo> skuInfoList = baseMapper.selectList(lqw);
        return skuInfoList;
    }

    //    获取所有新人专享商品
    @Override
    public List<SkuInfo> findNewPersionSkuInfoList() {
        LambdaQueryWrapper<SkuInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SkuInfo::getPublishStatus, 1); // 上架状态：0->下架；1->上架
        lqw.eq(SkuInfo::getIsNewPerson, 1); // 是否新人专享：0->否；1->是
        List<SkuInfo> skuInfoList = baseMapper.selectList(lqw);
        return skuInfoList;
    }

    // 根据商品id获取商品信息-4表连接sku_info 和sku_image-sku图片 和attr-商品属性和 sku_poster-海报表
    @Override
    public SkuInfoVo getSKuInfoVoBySkuId(Long skuId) {
        // 根据skuid查询
        SkuInfo skuInfo = baseMapper.selectById(skuId);

        //  根据skuid查询 sku_image-sku图片
        List<SkuImage> skuImageList = skuImageService.getImageBySkuIdList(skuId);

        // 根据skuid查询 attr-商品属性
        List<SkuAttrValue> skuAttrValueList = skuAttrValueService.getAttrValueBySkuIdList(skuId);

        // 根据skuid查询 sku_poster-海报表
        List<SkuPoster> skuPosterList = skuPosterService.getSkuPosterBySkuIdList(skuId);

        // 封装最近返回数据
        SkuInfoVo skuInfoVo = new SkuInfoVo();
        BeanUtils.copyProperties(skuInfo, skuInfoVo);
        skuInfoVo.setSkuImagesList(skuImageList);
        skuInfoVo.setSkuAttrValueList(skuAttrValueList);
        skuInfoVo.setSkuPosterList(skuPosterList);
        return skuInfoVo;
    }

    //    公平锁锁定商品
    @Override
    public Boolean checkAndLock(List<SkuStockLockVo> skuStockLockVoList, String orderNo) {
        // 不为空
        if (!CollectionUtils.isEmpty(skuStockLockVoList)) {
            throw new BusinessException(ResultCodeEnum.DATA_ERROR);
        }

        // 获取每个购物车每个商品库存，并上锁
        skuStockLockVoList.stream().forEach(skuStockLockVo -> {
            this.checkAndLock(skuStockLockVo);
        });

        // 只有有一个商品锁定失败，所有锁定成功的商品都解锁
        //    锁定所有商品
        boolean flag = skuStockLockVoList.stream().anyMatch(skuStockLockVo -> !skuStockLockVo.getIsLock());
        if (flag) { // 所有锁定成功的商品都解锁
            skuStockLockVoList.stream()
                    .filter(item -> item.getIsLock())
                    .forEach(item -> {
                        baseMapper.unlockStock(item.getSkuId(), item.getSkuNum());
                    });
            // 返回失败的状态
            return false;
        }

        // 所有商品都锁定了，redis字符串缓存相关数据 （方便后面解锁和减库存）     ===>  stock:info: 商品号，商品信息List集合
        redisTemplate.opsForValue().set(RedisConst.STOCK_INFO + orderNo, skuStockLockVoList);
        return true;
    }

    // 根据订单号减库存
    @Override
    public void minusStock(String orderNo) {
        // String类型-根据key从redis获取锁定库存信息     ===>  stock:info: 商品号
        List<SkuStockLockVo> skuStockLockVoList = (List<SkuStockLockVo>) redisTemplate.opsForValue().get(RedisConst.STOCK_INFO + orderNo);
        if (CollectionUtils.isEmpty(skuStockLockVoList)) { // 集合为空
            return;
        }

        // 遍历，根据商品id，减库存
        skuStockLockVoList.forEach(skuStockLockVo -> {
            baseMapper.minusStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
        });

        // 根据商品号，删除redis中付款是锁定的商品号  ===>  stock:info: 商品号，商品信息List集合
        redisTemplate.delete(RedisConst.STOCK_INFO + orderNo);

    }


    //2 遍历skuStockLockVoList得到每个商品，验证库存并锁定库存，具备原子性
    private void checkAndLock(SkuStockLockVo skuStockLockVo) {
        // 公平锁
        RLock rLock = this.redissonClient.getFairLock(RedisConst.SKUKEY_PREFIX + skuStockLockVo.getSkuId());
        // 加锁
        rLock.lock();
        try {
            // 根据商品id和商品数量，查看库存
            SkuInfo skuInfo = baseMapper.checkStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
            if (skuInfo == null) {
                skuStockLockVo.setIsLock(false); // 库存是否锁定
                return;
            }
            // 锁定库存：update
            Integer rows = baseMapper.lockStock(skuStockLockVo.getSkuId(), skuStockLockVo.getSkuNum());
            if (rows == 1) {
                skuStockLockVo.setIsLock(true); // 库存是否锁定
            }
        } finally {
            // 解锁
            rLock.unlock();
        }
    }
}

